package com.yeskery.nut.event;

import com.yeskery.nut.core.Order;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 智能应用监听器适配器
 * @author Yeskery
 * 2023/8/8
 */
public class SmartApplicationListenerAdapter implements SmartApplicationListener {

    /** 应用监听器 */
    private final ApplicationListener<ApplicationEvent> applicationListener;

    /**
     * 构建智能应用监听器适配器
     * @param applicationListener 应用监听器
     */
    @SuppressWarnings("unchecked")
    public SmartApplicationListenerAdapter(ApplicationListener<?> applicationListener) {
        this.applicationListener = (ApplicationListener<ApplicationEvent>) applicationListener;
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        applicationListener.onApplicationEvent(event);
    }

    @Override
    public boolean supportEventType(Class<? extends ApplicationEvent> eventType) {
        Type[] genericInterfaces = applicationListener.getClass().getGenericInterfaces();
        for (Type type : genericInterfaces) {
            if (type.getClass().equals(Class.class)) {
                continue;
            }
            ParameterizedType parameterizedType = (ParameterizedType) type;
            Class<?> clazz = (Class<?>) parameterizedType.getRawType();
            if (!clazz.equals(ApplicationListener.class)) {
                continue;
            }
            Type[] types = ((ParameterizedType) type).getActualTypeArguments();
            if (types.length != 1) {
                continue;
            }
            if (types[0] instanceof ParameterizedType) {
                parameterizedType = (ParameterizedType) types[0];
                clazz = (Class<?>) parameterizedType.getRawType();
            } else {
                clazz = (Class<?>) types[0];
            }
            if (eventType.isAssignableFrom(clazz)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int getOrder() {
        return Order.MIN;
    }
}
